/**
 * 前端性能优化工具函数
 * 包括防抖、节流、懒加载等性能优化功能
 */

/**
 * 防抖函数 (Debounce)
 * 在事件被触发n秒后再执行回调，如果在这n秒内又被触发，则重新计时
 * 
 * @param {Function} func - 需要防抖的函数
 * @param {number} wait - 等待时间（毫秒）
 * @param {boolean} immediate - 是否立即执行（首次触发时）
 * @returns {Function} 防抖后的函数
 * 
 * @example
 * // 搜索输入防抖
 * const debouncedSearch = debounce((value) => {
 *   console.log('搜索:', value);
 * }, 500);
 * 
 * input.addEventListener('input', (e) => debouncedSearch(e.target.value));
 */
export function debounce(func, wait = 300, immediate = false) {
  let timeout;
  
  return function executedFunction(...args) {
    const context = this;
    
    const later = () => {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    
    const callNow = immediate && !timeout;
    
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    
    if (callNow) func.apply(context, args);
  };
}

/**
 * 节流函数 (Throttle)
 * 规定时间内只执行一次函数，无论触发多少次
 * 
 * @param {Function} func - 需要节流的函数
 * @param {number} limit - 时间间隔（毫秒）
 * @returns {Function} 节流后的函数
 * 
 * @example
 * // 滚动事件节流
 * const throttledScroll = throttle(() => {
 *   console.log('滚动位置:', window.scrollY);
 * }, 200);
 * 
 * window.addEventListener('scroll', throttledScroll);
 */
export function throttle(func, limit = 300) {
  let inThrottle;
  let lastFunc;
  let lastRan;
  
  return function executedFunction(...args) {
    const context = this;
    
    if (!inThrottle) {
      func.apply(context, args);
      lastRan = Date.now();
      inThrottle = true;
    } else {
      clearTimeout(lastFunc);
      lastFunc = setTimeout(() => {
        if (Date.now() - lastRan >= limit) {
          func.apply(context, args);
          lastRan = Date.now();
        }
      }, Math.max(limit - (Date.now() - lastRan), 0));
    }
  };
}

/**
 * 组合式API专用的防抖Hook
 * 在Vue 3 Composition API中使用的防抖函数
 * 
 * @param {Function} func - 需要防抖的函数
 * @param {number} wait - 等待时间（毫秒）
 * @returns {Function} 防抖后的函数
 * 
 * @example
 * import { ref } from 'vue';
 * import { useDebouncedFn } from '@/utils/performance';
 * 
 * const searchValue = ref('');
 * const search = useDebouncedFn(() => {
 *   console.log('搜索:', searchValue.value);
 * }, 500);
 */
export function useDebouncedFn(func, wait = 300) {
  const debouncedFn = debounce(func, wait);
  
  // 在组件卸载时清理
  if (typeof onUnmounted === 'function') {
    const { onUnmounted } = require('vue');
    onUnmounted(() => {
      debouncedFn.cancel?.();
    });
  }
  
  return debouncedFn;
}

/**
 * 组合式API专用的节流Hook
 * 
 * @param {Function} func - 需要节流的函数
 * @param {number} limit - 时间间隔（毫秒）
 * @returns {Function} 节流后的函数
 */
export function useThrottledFn(func, limit = 300) {
  return throttle(func, limit);
}

/**
 * 懒加载图片
 * 使用Intersection Observer API实现图片懒加载
 * 
 * @param {string} selector - 图片选择器
 * @param {Object} options - Intersection Observer选项
 * @returns {IntersectionObserver} Observer实例
 * 
 * @example
 * // HTML: <img data-src="image.jpg" class="lazy-image" />
 * lazyLoadImages('.lazy-image');
 */
export function lazyLoadImages(selector = '[data-src]', options = {}) {
  const defaultOptions = {
    root: null,
    rootMargin: '50px',
    threshold: 0.01,
    ...options
  };
  
  const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        const src = img.dataset.src;
        
        if (src) {
          img.src = src;
          img.removeAttribute('data-src');
          observer.unobserve(img);
          
          // 添加加载完成的类
          img.addEventListener('load', () => {
            img.classList.add('loaded');
          });
        }
      }
    });
  }, defaultOptions);
  
  const images = document.querySelectorAll(selector);
  images.forEach(img => imageObserver.observe(img));
  
  return imageObserver;
}

/**
 * 请求空闲回调 (Request Idle Callback)
 * 在浏览器空闲时执行任务
 * 
 * @param {Function} callback - 回调函数
 * @param {Object} options - 选项
 * @returns {number} 请求ID
 * 
 * @example
 * requestIdleCallback(() => {
 *   console.log('浏览器空闲，执行低优先级任务');
 * });
 */
export function requestIdleCallback(callback, options = {}) {
  if ('requestIdleCallback' in window) {
    return window.requestIdleCallback(callback, options);
  }
  
  // Fallback for browsers that don't support requestIdleCallback
  return setTimeout(() => {
    const start = Date.now();
    callback({
      didTimeout: false,
      timeRemaining: () => Math.max(0, 50 - (Date.now() - start))
    });
  }, 1);
}

/**
 * 取消空闲回调
 * 
 * @param {number} id - 请求ID
 */
export function cancelIdleCallback(id) {
  if ('cancelIdleCallback' in window) {
    window.cancelIdleCallback(id);
  } else {
    clearTimeout(id);
  }
}

/**
 * 预加载资源
 * 预加载图片、脚本或样式表
 * 
 * @param {string} url - 资源URL
 * @param {string} type - 资源类型 ('image' | 'script' | 'style')
 * @returns {Promise} 加载Promise
 * 
 * @example
 * preloadResource('/images/large-image.jpg', 'image')
 *   .then(() => console.log('图片预加载完成'));
 */
export function preloadResource(url, type = 'image') {
  return new Promise((resolve, reject) => {
    let element;
    
    switch (type) {
      case 'image':
        element = new Image();
        element.src = url;
        break;
        
      case 'script':
        element = document.createElement('script');
        element.src = url;
        document.head.appendChild(element);
        break;
        
      case 'style':
        element = document.createElement('link');
        element.rel = 'stylesheet';
        element.href = url;
        document.head.appendChild(element);
        break;
        
      default:
        reject(new Error(`不支持的资源类型: ${type}`));
        return;
    }
    
    element.onload = resolve;
    element.onerror = reject;
  });
}

/**
 * 批量处理任务
 * 将大量任务分批处理，避免阻塞UI
 * 
 * @param {Array} items - 待处理的项目数组
 * @param {Function} handler - 处理函数
 * @param {number} batchSize - 每批处理数量
 * @returns {Promise} 处理Promise
 * 
 * @example
 * const items = Array.from({ length: 10000 }, (_, i) => i);
 * await batchProcess(items, (item) => {
 *   console.log('处理:', item);
 * }, 100);
 */
export async function batchProcess(items, handler, batchSize = 100) {
  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    
    // 处理当前批次
    await Promise.all(batch.map(item => handler(item)));
    
    // 让出主线程，避免阻塞UI
    await new Promise(resolve => setTimeout(resolve, 0));
  }
}

/**
 * 性能监控
 * 监控函数执行时间
 * 
 * @param {Function} func - 要监控的函数
 * @param {string} label - 标签名称
 * @returns {Function} 包装后的函数
 * 
 * @example
 * const slowFunction = performanceMonitor(() => {
 *   // 耗时操作
 * }, '慢函数');
 */
export function performanceMonitor(func, label = 'function') {
  return function monitoredFunction(...args) {
    const start = performance.now();
    const result = func.apply(this, args);
    const end = performance.now();
    
    console.log(`[性能] ${label} 执行时间: ${(end - start).toFixed(2)}ms`);
    
    // 如果返回Promise，等待完成后再计时
    if (result instanceof Promise) {
      return result.then(res => {
        const endAsync = performance.now();
        console.log(`[性能] ${label} 异步执行时间: ${(endAsync - start).toFixed(2)}ms`);
        return res;
      });
    }
    
    return result;
  };
}

/**
 * 内存优化：大对象深拷贝
 * 使用结构化克隆算法（比JSON.parse(JSON.stringify())更快）
 * 
 * @param {any} obj - 要克隆的对象
 * @returns {any} 克隆后的对象
 */
export function deepClone(obj) {
  if ('structuredClone' in window) {
    return structuredClone(obj);
  }
  
  // Fallback
  return JSON.parse(JSON.stringify(obj));
}

/**
 * 检查是否为慢速网络
 * 
 * @returns {boolean} 是否为慢速网络
 */
export function isSlowNetwork() {
  if ('connection' in navigator && 'effectiveType' in navigator.connection) {
    const type = navigator.connection.effectiveType;
    return type === 'slow-2g' || type === '2g' || type === '3g';
  }
  return false;
}

/**
 * 获取网络信息
 * 
 * @returns {Object} 网络信息
 */
export function getNetworkInfo() {
  if ('connection' in navigator) {
    const conn = navigator.connection;
    return {
      type: conn.effectiveType || 'unknown',
      downlink: conn.downlink || 0,
      rtt: conn.rtt || 0,
      saveData: conn.saveData || false
    };
  }
  return null;
}

// 默认导出所有函数
export default {
  debounce,
  throttle,
  useDebouncedFn,
  useThrottledFn,
  lazyLoadImages,
  requestIdleCallback,
  cancelIdleCallback,
  preloadResource,
  batchProcess,
  performanceMonitor,
  deepClone,
  isSlowNetwork,
  getNetworkInfo
};

